/**
*    CTR - Centro Tecnologia Rocci
*    Open Source Java Classic Game Toolkit
*
*    (C) 2010, CTR - Centro Tecnologia Rocci
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation;
*    version 2.1 of the License.
*
*/
package it.ctr.game.toolkit.level.editor;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.mojang.mario.level.Level;

public class LevelEditor extends JFrame implements ActionListener {

	private static final long serialVersionUID = -1234000000000000012L;
	private JTabbedPane tabbedPanel;
	private JSplitPane splitPanel;
	private JPanel optionPanel;
	private LevelViewer levelViewer;
	private JPanel brickPanel;
	private JPanel componentPanel;
	private JPanel controlPanel;
	private BrickViewer levelBrick;
	private ComponentViewer componentViewer;
	private JButton loadButton;
    private JButton saveButton;
    private JButton newButton;
    private JTextField fileNameField;
    private JTextField nameField;
    private JSpinner timeField;
    private JSpinner widthField;
    private JSpinner heightField;
    private JTextArea descriptionField;
    
	private static final String PREFERRED_LOOK_AND_FEEL = "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel";
	
	public LevelEditor() {
		initComponents();
	}

	private void initComponents() {
      JPanel borderPanel = new JPanel(new BorderLayout());
      borderPanel.add(BorderLayout.CENTER, getSplitPanel());
      borderPanel.add(BorderLayout.NORTH, getTabbedPanel());
      setContentPane(borderPanel);
      setSize(800, 600);	
	}

	public void addNotify() {
		super.addNotify();
	      levelViewer.setLayer(-1);
	}

	private JPanel getBrickPanel() {
		if (brickPanel == null) {
			brickPanel = new JPanel();
			brickPanel.setBorder(BorderFactory.createTitledBorder(null, "Componenti", TitledBorder.LEADING, TitledBorder.ABOVE_TOP, new Font("SansSerif", Font.BOLD,12), new Color(59, 59, 59)));
			brickPanel.add(getLevelBrick());
		}
		return brickPanel;
	}
	
	private BrickViewer getLevelBrick() {
		if (levelBrick == null) {
			levelBrick = new BrickViewer();
			levelBrick.addTilePickChangedListener(this);
		}
		return levelBrick;
	}

	private JPanel getComponentPanel() {
		if (componentPanel == null) {
			componentPanel = new JPanel();
			componentPanel.setBorder(BorderFactory.createTitledBorder(null, "Componenti", TitledBorder.LEADING, TitledBorder.ABOVE_TOP, new Font("SansSerif", Font.BOLD,12), new Color(59, 59, 59)));
			componentPanel.add(getComponentViewer());
		}
		return componentPanel;
	}
	
	private ComponentViewer getComponentViewer() {
		if (componentViewer == null) {
			componentViewer = new ComponentViewer();
			componentViewer.addTilePickChangedListener(this);
		}
		return componentViewer;
	}
	
	private JPanel getControlPanel() {
		if (controlPanel == null) {
			controlPanel = new JPanel();
			controlPanel.setBorder(BorderFactory.createTitledBorder(null, "Livello", TitledBorder.LEADING, TitledBorder.ABOVE_TOP, new Font("SansSerif", Font.BOLD,12), new Color(59, 59, 59)));
			controlPanel.setLayout(new FlowLayout());
			controlPanel.setPreferredSize(new Dimension(420,440));
			loadButton = new JButton("Apri");
			loadButton.setPreferredSize(new Dimension(63,26));
	        saveButton = new JButton("Salva");
	        saveButton.setPreferredSize(new Dimension(63,26));
	        newButton = new JButton("Nuovo");
	        newButton.setPreferredSize(new Dimension(63,26));
	        fileNameField = new JTextField("c:\\1.ctr.game.level", 18);
	        nameField = new JTextField("Livello 1", 30);
			SpinnerModel sm = new SpinnerNumberModel(200, 50, 1000, 5);
	        timeField = new JSpinner();
			timeField.setModel(sm);
			timeField.setPreferredSize(new Dimension(63,26));
			sm = new SpinnerNumberModel(200, 40, 1000, 4);
	        widthField = new JSpinner();
	        widthField.setModel(sm);
	        widthField.setPreferredSize(new Dimension(63,26));
			sm = new SpinnerNumberModel(14, 4, 26, 2);
			heightField = new JSpinner();
			heightField.setModel(sm);
			heightField.setPreferredSize(new Dimension(63,26));
			descriptionField = new JTextArea();
			descriptionField.setText("Inserire la descrizione del livello o le istruzioni di gioco");
			descriptionField.setPreferredSize(new Dimension(380,250));
	        loadButton.addActionListener(this);
	        saveButton.addActionListener(this);
	        newButton.addActionListener(this);
	        controlPanel.add(new JLabel("Lunghezza"));
	        controlPanel.add(widthField);
	        controlPanel.add(new JLabel("Altezza"));
	        controlPanel.add(heightField);
	        controlPanel.add(new JLabel("Tempo"));
	        controlPanel.add(timeField);
	        controlPanel.add(new JLabel("Nome"));
	        controlPanel.add(nameField);
	        controlPanel.add(descriptionField);
	        controlPanel.add(new JLabel("File"));
	        controlPanel.add(fileNameField);
	        controlPanel.add(loadButton);
	        controlPanel.add(saveButton);
	        controlPanel.add(new JLabel("Attenzione, salvare prima di premere il tasto!  "));
	        controlPanel.add(newButton);
		}
		return controlPanel;
	}
	
	private LevelViewer getLevelViewer() {
		if (levelViewer == null) {
			levelViewer = new LevelViewer(levelBrick);
		}
		return levelViewer;
	}

	private JPanel getOptionPanel() {
		if (optionPanel == null) {
			optionPanel = new JPanel();
			optionPanel.add(getBrickPanel());
			optionPanel.add(getComponentPanel());
			optionPanel.add(getControlPanel());
		}
		return optionPanel;
	}

	private JSplitPane getSplitPanel() {
		if (splitPanel == null) {
			splitPanel = new JSplitPane();
			splitPanel.setBorder(null);
			splitPanel.setDividerLocation(150);
			splitPanel.setOrientation(JSplitPane.VERTICAL_SPLIT);
			splitPanel.setContinuousLayout(false);
			splitPanel.setBottomComponent(new JScrollPane(getOptionPanel()));
			splitPanel.setTopComponent(new JScrollPane(getLevelViewer()));
		}
		return splitPanel;
	}

	private JTabbedPane getTabbedPanel() {
		if (tabbedPanel == null) {
			tabbedPanel = new JTabbedPane();
			tabbedPanel.setPreferredSize(new Dimension(800,30));
			tabbedPanel.addTab("Anteprima ", new ImageIcon(getClass().getResource("/it/ctr/game/toolkit/image/play.png")), null);
			tabbedPanel.addTab("Livello Dietro", null);
			tabbedPanel.addTab("Livello Centro", null);
			tabbedPanel.addTab("Livello Avanti", null);
			tabbedPanel.addChangeListener(
				new ChangeListener() { 
					public void stateChanged(ChangeEvent e) {
						levelViewer.setLayer(tabbedPanel.getSelectedIndex()-1);
						levelViewer.repaint();
					} 
			    }
			); 

		}
		return tabbedPanel;
	}

	public static void main(String[] args) {
		try {
			UIManager.setLookAndFeel(PREFERRED_LOOK_AND_FEEL);
		} catch (Exception e) {
			e.printStackTrace();
		}
		LevelEditor frame = new LevelEditor();
		frame.setDefaultCloseOperation(LevelEditor.EXIT_ON_CLOSE);
		frame.setTitle("CTR Game Toolkit - Level Editor");
		frame.getContentPane().setPreferredSize(frame.getSize());
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);	
	}

	public void actionPerformed(ActionEvent e) {
		try
        {
            if (e.getSource() == loadButton)
            {
                levelViewer.setLevel(Level.load(new DataInputStream(new FileInputStream(fileNameField.getText().trim()))));
                widthField.setValue(levelViewer.getLevel().width);
                heightField.setValue(levelViewer.getLevel().height);
                timeField.setValue(levelViewer.getLevel().time);
            }
            if (e.getSource() == saveButton)
            {
            	levelViewer.getLevel().save(new DataOutputStream(new FileOutputStream(fileNameField.getText().trim())));
            }
            if (e.getSource() == newButton)
            {
                Level level = new Level(Integer.valueOf(widthField.getValue().toString()), Integer.valueOf(heightField.getValue().toString()));
                level.time = Integer.valueOf(timeField.getValue().toString());
                levelViewer.setLevel(level);
                update(getGraphics());
            }
        }
        catch (Exception ex)
        {
            JOptionPane.showMessageDialog(this, ex.toString(), "Errore nell'apertura o salvataggio del livello", JOptionPane.ERROR_MESSAGE);
        }
		
	}
	
    public void setSelectedBrick(byte selectedBrick)
    {

    }

}
